package com.hua.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hua.common.Response;
import com.hua.common.ResponseCode;
import com.hua.domain.Discountcard;
import com.hua.domain.User;
import com.hua.domain.Userbindingdiscountcard;
import com.hua.exception.BusinessException;
import com.hua.mapper.DiscountcardMapper;
import com.hua.mapper.UserMapper;
import com.hua.mapper.UserbindingdiscountcardMapper;
import com.hua.service.UserService;
import com.hua.util.JwtUtil;
import com.hua.util.RedisCache;
import com.hua.util.ResultUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

import static com.hua.constant.RedisConstant.REDIS_USER_ID;

/**
 * ClassName:UserServiceImpl
 * Package:com.hua.service.impl
 * Description:
 *
 * @data: 2022/10/18 18:24
 * @author:ChenJH
 */

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private static final String USER_ID = "userId";

    @Resource
    private RedisCache redisCache;

    @Resource
    private DiscountcardMapper discountcardMapper;

    @Resource
    private UserbindingdiscountcardMapper userbindingdiscountcardMapper;

    public Response<User> login(User user) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserAccount, user.getUserAccount());
        User userByAccount = getOne(queryWrapper);
        if (!userByAccount.getUserAccount().equals(user.getUserAccount()) ||
                !userByAccount.getUserPassword().equals(user.getUserPassword())) {
            throw new BusinessException(ResponseCode.LOGIN_FAIL, "登录失败");
        }
        String token = JwtUtil.createJWT(userByAccount.getUserId().toString());
        redisCache.setCacheObject(REDIS_USER_ID + userByAccount.getUserId(), userByAccount,30, TimeUnit.MINUTES);
        redisCache.setCacheObject(USER_ID, +userByAccount.getUserId(),30,TimeUnit.MINUTES);
        userByAccount.setUserPassword(null);
        return ResultUtils.success(ResponseCode.SUCCESS, userByAccount, token);
    }

    @Override
    public Response<String> toLogOut() {
        Integer userId = redisCache.getCacheObject(USER_ID);
        User userInfo = redisCache.getCacheObject(REDIS_USER_ID + userId);
        if (userInfo == null) {
            throw new BusinessException(ResponseCode.NOT_LOGIN, "用户位登录");
        } else {
            redisCache.deleteObject(USER_ID);
            redisCache.deleteObject(REDIS_USER_ID + userId);
            return ResultUtils.success(ResponseCode.LOGOUT_SUCCESS, "退出成功");
        }
    }

    @Override
    public User getUserInfo() {
        Integer userId = redisCache.getCacheObject(USER_ID);
        User user = redisCache.getCacheObject(REDIS_USER_ID + userId);
        if (user == null) {
            throw new BusinessException(ResponseCode.SESSION_EXPIRED);
        }
        user.setUserPassword(null);
        return user;
    }


    private  Queue<Discountcard> queue = new ConcurrentLinkedDeque<>();
    private  BlockingQueue<Integer> DbQueue = new LinkedBlockingQueue<>();
    public Response<String> sendDisCount(Integer discountCardId){
        Discountcard discountcard = discountcardMapper.selectById(discountCardId);
        if(discountcard.getNum()==0){
            throw new BusinessException(ResponseCode.SYSTEM_ERROR,"请添加优惠卷数量再派发");
        }
        boolean add =true;
        for (int i = 1; i <= discountcard.getNum(); i++) {
             add = queue.add(discountcard);
            if(!add){
                break;
            }
        }
        if(!add){
            throw new BusinessException(ResponseCode.SYSTEM_ERROR,"添加失败");
        }
        saveDb(discountCardId);
        return ResultUtils.success(ResponseCode.SUCCESS,"发卷成功");
    }
    public void saveDb(Integer discountCardId){
        new Thread(()->{
            while (true){
                try {
                    Integer uid = DbQueue.take();
                    Userbindingdiscountcard userbindingdiscountcard = new Userbindingdiscountcard();
                    userbindingdiscountcard.setUid(uid);
                    userbindingdiscountcard.setDiscountId(discountCardId);
                    if(userbindingdiscountcardMapper.insert(userbindingdiscountcard)>0){
                        log.info("用户:"+uid+"抢卷成功");
                    }
                    log.error("线程出现异常");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
    @Override
    @Transactional
    public Response<String> getDiscount(Integer userId,Integer discountCardId) {
        ReentrantLock lock = new ReentrantLock();
        try {
            //加锁
            lock.lock();
            //设置缓存 查缓存如果缓存中没有这个值，查一下数据库
//            Discountcard discountcard = redisCache.getCacheObject("discount");
//            if(Objects.isNull(discountcard)) {
//            Discountcard discountcard = discountcardMapper.selectById(discountCardId);
////            }
//            //查看库存
//            Integer num = discountcard.getNum();
//            //库存中没有 则直接返回卷已经抢完
//            if(num==0){
//                return ResultUtils.success(ResponseCode.SUCCESS,"卷已经抢完");
//            }
//            //走到这里证明用户已经抢到卷 这个数据表用于记录 各个用户和优惠卷的绑定关系
//            Userbindingdiscountcard userbindingdiscountcard = new Userbindingdiscountcard();
//            userbindingdiscountcard.setDiscountId(discountCardId);
//            userbindingdiscountcard.setUid(userId);
//
//            if(userbindingdiscountcardMapper.insert(userbindingdiscountcard)>0){
//                discountcard.setNum(--num);
//                discountcardMapper.updateById(discountcard);
//                return ResultUtils.success(ResponseCode.SUCCESS,"恭喜您,成功抢到卷");
//            }
//            throw new BusinessException(ResponseCode.SYSTEM_ERROR,"卷已经抢完~");
            Discountcard poll = queue.poll();
            if (poll == null){
                poll.setId(discountCardId);
                poll.setNum(0);
                LambdaQueryWrapper<Discountcard> queryWrapper = new LambdaQueryWrapper<Discountcard>();
                queryWrapper.eq(Discountcard::getId,poll.getId());
                discountcardMapper.updateById(poll);
                return ResultUtils.success(ResponseCode.SUCCESS,"卷已经抢完");
            }
            DbQueue.put(userId);
            return ResultUtils.success(ResponseCode.SUCCESS,"抢到了");
        }catch (Exception e){
            return ResultUtils.success(ResponseCode.SUCCESS,"卷已经抢完");
        } finally {
            lock.unlock();
        }
    }
}
